﻿using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;

namespace Gmantis.Controls.Chart
{
    internal interface IMeasureSymbolWidth
    {
    }

    public class HighLowSeries : XYDataSeries, IMeasureSymbolWidth
    {
        // Fields
        private Binding _highValuesBinding;
        private Binding _lowValuesBinding;
        protected List<object> alHi = new List<object>();
        protected List<object> alLo = new List<object>();
        private static DependencyProperty HighValuesProperty = DependencyProperty.Register("HighValues", typeof(DoubleCollection), typeof(HighLowSeries), new PropertyMetadata(null, new PropertyChangedCallback(HighLowSeries.HighValuesChanged)));
        public static readonly DependencyProperty HighValuesSourceProperty = Utils.RegisterProperty("HighValuesSource", typeof(IEnumerable), typeof(HighLowSeries), new PropertyChangedCallback(DataSeries.OnChangeValues));
        internal int Index;
        internal bool IsGantt;
        private static DependencyProperty LowValuesProperty = DependencyProperty.Register("LowValues", typeof(DoubleCollection), typeof(HighLowSeries), new PropertyMetadata(null, new PropertyChangedCallback(HighLowSeries.LowValuesChanged)));
        public static readonly DependencyProperty LowValuesSourceProperty = Utils.RegisterProperty("LowValuesSource", typeof(IEnumerable), typeof(HighLowSeries), new PropertyChangedCallback(DataSeries.OnChangeValues));

        // Methods
        internal override string[] GetDataNamesInternal()
        {
            return new string[] { "Values", "XValues", "LowValues", "HighValues" };
        }

        internal override ValueCoordinate[] GetValueCoordinates(bool check)
        {
            if (check)
            {
                return new ValueCoordinate[] { base.Check(ValueCoordinate.Y), base.Check(ValueCoordinate.X), base.Check(ValueCoordinate.Y), base.Check(ValueCoordinate.Y) };
            }
            return new ValueCoordinate[] { ValueCoordinate.Y, ValueCoordinate.X, ValueCoordinate.Y, ValueCoordinate.Y };
        }

        internal override double[,] GetValues()
        {
            if (base.datavalues == null)
            {
                if (base.ValueBinding == null)
                {
                    DataSeries.InitList(base.listY, base.ValuesSource, base.Values);
                }
                if (base.XValueBinding == null)
                {
                    DataSeries.InitList(base.listX, base.XValuesSource, base.XValues);
                }
                if (this.LowValueBinding == null)
                {
                    DataSeries.InitList(this.alLo, this.LowValuesSource, this.LowValues);
                }
                if (this.HighValueBinding == null)
                {
                    DataSeries.InitList(this.alHi, this.HighValuesSource, this.HighValues);
                }
                int maxCount = DataSeries.GetMaxCount(new IList[] { base.listY, base.listX, this.alLo, this.alHi });
                if (base.listX.Count == 0)
                {
                    if (this.IsGantt)
                    {
                        for (int i = 0; i < maxCount; i++)
                        {
                            base.listX.Add(this.Index);
                        }
                    }
                    else
                    {
                        for (int j = 0; j < maxCount; j++)
                        {
                            base.listX.Add(j);
                        }
                    }
                }
                if (base.listY.Count == 0)
                {
                    base.datavalues = base.CreateValues(new IList[] { this.alLo, base.listX, this.alLo, this.alHi });
                }
                else
                {
                    base.datavalues = base.CreateValues(new IList[] { base.listY, base.listX, this.alLo, this.alHi });
                }
                if (base.isTimeValues == null)
                {
                    base.isTimeValues = new bool[4];
                }
                base.isTimeValues[0] = base.IsTimeData(base.listY);
                base.isTimeValues[1] = base.IsTimeData(base.listX);
                base.isTimeValues[2] = base.IsTimeData(this.alLo);
                base.isTimeValues[3] = base.IsTimeData(this.alHi);
            }
            return base.datavalues;
        }

        private static void HighValuesChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            ((DataSeries)obj).FirePropertyChanged("HighValues");
        }

        private static void LowValuesChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            ((DataSeries)obj).FirePropertyChanged("LowValues");
        }

        internal override void SetResolvedValues(int index, object[] vals)
        {
            base.SetResolvedValues(index, vals);
            switch (index)
            {
                case 2:
                    this.alLo.Clear();
                    this.alLo.AddRange(vals);
                    return;

                case 3:
                    this.alHi.Clear();
                    this.alHi.AddRange(vals);
                    return;
            }
        }

        // Properties
        public Binding HighValueBinding
        {
            get
            {
                return this._highValuesBinding;
            }
            set
            {
                if (this._highValuesBinding != value)
                {
                    this._highValuesBinding = value;
                    base.Dirty = true;
                    base.FirePropertyChanged("HighValueBinding");
                }
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public DoubleCollection HighValues
        {
            get
            {
                return (DoubleCollection)base.GetValue(HighValuesProperty);
            }
            set
            {
                base.SetValue(HighValuesProperty, value);
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public IEnumerable HighValuesSource
        {
            get
            {
                return (IEnumerable)base.GetValue(HighValuesSourceProperty);
            }
            set
            {
                base.SetValue(HighValuesSourceProperty, value);
            }
        }

        public Binding LowValueBinding
        {
            get
            {
                return this._lowValuesBinding;
            }
            set
            {
                if (this._lowValuesBinding != value)
                {
                    this._lowValuesBinding = value;
                    base.Dirty = true;
                    base.FirePropertyChanged("LowValueBinding");
                }
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public DoubleCollection LowValues
        {
            get
            {
                return (DoubleCollection)base.GetValue(LowValuesProperty);
            }
            set
            {
                base.SetValue(LowValuesProperty, value);
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public IEnumerable LowValuesSource
        {
            get
            {
                return (IEnumerable)base.GetValue(LowValuesSourceProperty);
            }
            set
            {
                base.SetValue(LowValuesSourceProperty, value);
            }
        }

        public override Binding[] MemberPaths
        {
            get
            {
                if (((base.ValueBinding == null) && (base.XValueBinding == null)) && ((this.HighValueBinding == null) && (this.LowValueBinding == null)))
                {
                    return null;
                }
                return new Binding[] { base.ValueBinding, base.XValueBinding, this.LowValueBinding, this.HighValueBinding };
            }
        }
    }
}
